package com.huajx.tuopuda.client.udp.handler;

import com.huajx.core.Hboot;
import com.huajx.tuopuda.client.udp.TuopudaException;
import com.huajx.tuopuda.client.udp.TuopudaUtil;
import com.huajx.tuopuda.client.udp.config.SchoolConfig;
import com.huajx.tuopuda.client.udp.config.SettingConfig;
import com.huajx.util.HexUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.*;

/**
 * @author: lisa 叶新华
 * @create: 2019-09-27 01:54
 */
public abstract class AbstractTuopudaHandler {
    private static final Logger logger = LoggerFactory.getLogger(AbstractTuopudaHandler.class);
    //public final static String SERVER_URL = "http://127.0.0.1:8080/wechat";
    public final static String SERVER_URL = "http://wx.52ycm.com:80/wechat";

    protected SettingConfig settingConfig = Hboot.config(SettingConfig.class);
    protected SchoolConfig schoolConfig = Hboot.config(SchoolConfig.class);

    public abstract void send(String ip, int port, int sn);

    protected byte[] sendAndReceive(String ip, int port, byte[] sendBytes) throws TuopudaException {
//        String responseMsg = "";
        //创建客户端的DatagramSocket对象，不必传入地址和对象
        byte[] bytes=new byte[0];
        DatagramSocket client = null;
        try {
            client = new DatagramSocket();

            //封装要发送目标的地址
            InetAddress address = InetAddress.getByName(ip);
            //封装要发送的DatagramPacket的对象，由于要发送到目的主机，所以要加上地址和端口号
            DatagramPacket sendPacket = new DatagramPacket(sendBytes, sendBytes.length, address, port);

            //发送数据
            client.send(sendPacket);
            if(logger.isInfoEnabled()) {
                logger.info("已发送命令: {}", HexUtil.bytesToHex(sendBytes));
            }

            byte[] responseBytes = new byte[34];
            //创建响应信息的DatagramPacket对象
            DatagramPacket responsePacket = new DatagramPacket(responseBytes, responseBytes.length);
            //等待响应信息，同服务端一样，客户端也会在这一步阻塞，直到收到一个数据包
            client.setSoTimeout(settingConfig.getTimeout());
            client.receive(responsePacket);

            //解析数据包内容
            bytes = responsePacket.getData();

            if(logger.isInfoEnabled()) {
                logger.info("接收到消息: {}", HexUtil.bytesToHex(bytes));
            }

//            responseMsg = BitUtil.bytesToHex(responsePacket.getData());//new String(, 0, responsePacket.getLength());
//        } catch (SocketException e) {
//            throw new TuopudaException("通讯出错，请检查", e);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭客户端
            if (client != null) {
                client.close();
                client = null;
            }
        }

        return bytes;
    }

    public byte[] sendAndReceive(String ip, int port, String msg) throws TuopudaException {
        byte[] sendBytes = HexUtil.hexToBytes(msg);
        return sendAndReceive(ip, port, sendBytes);
    }

    protected byte[] encode(int sn, int function, Encode encode) {
        byte[] bytes = new byte[34];
        int checkSum = 0;
        bytes[0] = 0x7E;    //开始位
        bytes[33] = 0x0D;   //结束位

        checkSum += TuopudaUtil.replaceBytes(bytes, sn, 1, 2);
        checkSum += TuopudaUtil.replaceBytes(bytes, function, 3, 2);

        if (encode != null) {
            checkSum += encode.encode(bytes);
        }

        TuopudaUtil.replaceBytes(bytes, checkSum, 31, 2); //补较验和
        return bytes;
    }

    /**
     * 编码处理器
     */
    protected interface Encode {
        int encode(byte bytes[]);
    }
}
